<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 浅拷贝：
        // ——拷贝基本类型的值
        // ——拷贝引用类型的引用（地址）
        // 对象拷贝时，如果属性值是引用数据类型时，这时候我们传递的只是一个地址。
        // 因此子对象在访问该属性时，会根据地址回溯到父对象指向的堆内存中，即父子对象发生了关联，两者的属性值会指向同一内存空间。
        
        var person1 = {
            name: "Lily",
            age: 20,
            hobby: ["sing", "play", "sleep"],
            dog: {
                name: "小白",
                weight: 60
            }
        };
        // 浅拷贝不是直接赋值，而是新建了一个对象，然后将源对象的属性都一一复制过来。
        var person2 = {};
        for (var key in person1) {
            person2[key] = person1[key];
        }
        console.log(person2);
        
        person1.name = "Jack";
        person2.name; //'Lily'
        // 浅绑定
        person1.hobby.push("swim");
        person1.hobby; //['sing', 'play', 'sleep', 'swim']
        person2.hobby; // ['sing', 'play', 'sleep', 'swim']

        var person1 = {
            name: "Lily",
            hobby: ["sing", "play", "sleep"]
        };
        function copy(obj1) {
            var obj2 = {};
            for (var i in obj1) {
                obj2[i] = obj1[i];
            }
            return obj2;
        }
        var person2 = copy(person1);
        person1.hobby.push("eat");
        console.log(person2.hobby); //['sing', 'play', 'sleep', 'eat']
        person1.name = "jack";
        person2.name; //'Lily'

        // 深拷贝 = 浅拷贝 + 递归 demo9
        // 拷贝基本类型的值
        // 拷贝引用类型时（比如数组和或对象）,使用递归,把父对象中所有属于引用类型的对象都遍历赋给子对象即可.
        var person1 = {
            name: "Lily",
            hobby: ["sing", "play", "sleep"],
            friends: [{
                    name: "小明",
                    age: 18
                },
                {
                    name: "小红",
                    age: 20
                },
                {
                    name: "小白",
                    age: 22
                }
            ]
        };
        var person2;
        function copy(origin, target) {
            target = target || {};
            for (var name in origin) {
                if (origin[name] != null && typeof origin[name] == "object") {
                    target[name] = Object.prototype.toString.call(origin[name]).slice(8, -1) == "Array" ? [] : {};
                    copy(origin[name], target[name]);
                } else {
                    target[name] = origin[name];
                }
            }
            return target;
        }
        person2 = copy(person1, person2); //{name: 'Lily', hobby: Array(3), friends: Array(3)}
        person2.hobby.push("123"); //person2.hobby--['sing', 'play', 'sleep', '123']
        person1.hobby; // ['sing', 'play', 'sleep']
        person2.friends[0].age = 30; //30
        person1.friends[0].age; //18
        person2.name = "c" 
        person1.name; //Lily
        console.log(person1); //没有改变
        
        /**
            Object.prototype.toString.call("name")
            '[object String]' 
            Object.prototype.toString.call("name").slice(8, -1)
            String
            Object.prototype.toString.call([])
            '[object Array]'
            Object.prototype.toString.call("name").slice(8, -1)
            Array
        */

        var person1 = {
            name: "Lily",
            hobby: ["sing", "play", "sleep"]
        };
        var person2 = {};
        function copy(origin, target) {
            var target = target || {};
            //最初的时候给它一个初始值

            for (var name in origin) {
            //先判断一下obj[name]是不是一个对象
            if (origin[name] != null && typeof origin[name] === "object") {
                //如果是对象的话，需要判断是{}还是[]
                target[name] = origin[name].constructor === Array ? [] : {};
                //然后来无限调用函数自己 递归思想
                copy(origin[name], target[name]);
            } else {
                target[name] = origin[name];
                //如果不是对象，基本数据类型可以直接赋值
            }
            }
            return target;
        }
        person2 = copy(person1, person2);
        person1.hobby.push("eat");
        console.log(person2.hobby); //['sing', 'play', 'sleep']
    </script>
</body>
</html>